#include "ClientManager.h"

ClientManager::ClientManager()
{
}

bool ClientManager::IsValidClient(const QString &group, const QString &name) const
{
	return GetClientIndex(group, name) != -1;
}

bool ClientManager::IsValidClient(const QString &fullName) const
{
	return GetClientIndex(fullName) != -1;
}

bool ClientManager::IsValidAddress(const QHostAddress &addr) const
{
	return GetAddressIndex(addr) != -1;
}

void ClientManager::RemoveAllClients()
{
	_clients.clear();
	_groups.clear();
}

bool ClientManager::RemoveClient(const QString &group, const QString &name)
{
	int idx = GetClientIndex(group, name);
	if (idx != -1)
	{
		_clients.removeAt(idx);
		if (GetGroupMemberCount(group) == 0)
			_groups.removeOne(group);
		return true;
	}
	return false;
}

bool ClientManager::AddClient(const QString &group, const QString &name, const QHostAddress &addr)
{
	if (!addr.isNull() && !IsValidClient(group, name))
	{
		Client client;
		client.group = group;
		client.name = name;
		client.groupName = group + ':' + name;
		client.addr = addr;
		_clients.append(client);
		if (IsNewGroup(group))
			_groups.append(group);
		return true;
	}
	return false;
}

bool ClientManager::UpdateClient(const QString &group, const QString &name, const QHostAddress &addr)
{
	int idx = GetAddressIndex(addr);
	if (idx != -1)
	{
		bool modGroup = (_clients[idx].group != group);
		if (modGroup || _clients[idx].name != name)
		{
			if (modGroup)
			{
				if (GetGroupMemberCount(_clients[idx].group) == 1)
					_groups.removeOne(_clients[idx].group);
				if (IsNewGroup(group))
					_groups.append(group);
			}
			_clients[idx].group = group;
			_clients[idx].name = name;
			_clients[idx].groupName = group + ':' + name;
			return true;
		}
	}
	return false;
}

bool ClientManager::IsNewGroup(const QString &group) const
{
	return !_groups.contains(group);
}

int ClientManager::GetClientCount() const
{
	return _clients.count();
}

void ClientManager::GetDisplayedNames(const QString &group, QStringList &displayedNames) const
{
	if (group != "ALL")
	{
		for (int i = 0; i < _clients.count(); i++)
		{
			if (_clients.at(i).group == group)
				displayedNames.append(_clients.at(i).name);
		}
	}
	else
	{
		for (int i = 0; i < _clients.count(); i++)
			displayedNames.append(_clients.at(i).groupName);
	}
}

bool ClientManager::GetClientInfo(const QHostAddress &addr, QString &name, QString &group) const
{
	int idx = GetAddressIndex(addr);
	if (idx != -1)
	{
		name = _clients.at(idx).name;
		group = _clients.at(idx).group;
		return true;
	}
	return false;
}


QHostAddress ClientManager::GetAddress(const QString &groupName) const
{
	QHostAddress addr = QHostAddress::Null;
	int idx = GetClientIndex(groupName);
	if (idx != -1)
		addr = _clients.at(idx).addr;
	return addr;
}

QHostAddress ClientManager::GetAddress(const QString &group, const QString &name) const
{
	return GetAddress(group + ':' + name);
}

int ClientManager::GetGroupMemberCount(const QString &group) const
{
	int cnt = 0;
	if (group == "ALL")
		cnt = _clients.count();
	else
	{
		for (int i = 0; i < _clients.count(); i++)
		if (_clients.at(i).group == group)
			cnt++;
	}
	return cnt;
}

int ClientManager::GetClientIndex(const QString &group, const QString &name) const
{
	return GetClientIndex(group + ':' + name);
}

int ClientManager::GetClientIndex(const QString &groupName) const
{
	int idx = -1;
	for (int i = 0; i < _clients.count() && idx == -1; i++)
	{
		if (_clients.at(i).groupName == groupName)
			idx = i;
	}
	return idx;
}

int ClientManager::GetAddressIndex(const QHostAddress &addr) const
{
	int idx = -1;
	for (int i = 0; i < _clients.count() && idx == -1; i++)
	{
		if (_clients.at(i).addr == addr)
			idx = i;
	}
	return idx;
}

static ClientManager g_clientManager;
ClientManager *GetClientManager()
{
	return &g_clientManager;
}
